﻿using Microsoft.Extensions.Primitives;
using System.Diagnostics;
using ED.Common.Extensions;

namespace ED.ApiGateWay.Middleware
{
    /// <summary>
    /// 访问统计中间件
    /// </summary>
    public class GateWayMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILogger<GateWayMiddleware> logger;

        //构造函数只在构建请求管道的时候调用一次,不是每个请求都创建一次
        public GateWayMiddleware(RequestDelegate next, ILogger<GateWayMiddleware> logger)
        {
            this.next = next;
            this.logger = logger;
        }

        public static long RunningCounter = 0;
        public static long TotalCounter = 0;

        public async Task InvokeAsync(HttpContext ctx)
        {
            var count = Interlocked.Increment(ref RunningCounter);
            var totalCount = Interlocked.Increment(ref TotalCounter);
            var st = new Stopwatch();
            st.Start();
            ctx.Request.Headers.TryGetValue("Authorization", out StringValues jwtStr);
            //var jwtUser = JwtCommon.SerializeJWT(jwtStr.To(true, ""));
            //Utils.UNHeader(ctx, jwtUser);

            string requestPath = $"{ctx.Request.Scheme}://{ctx.Request.Host}{ctx.Request.Path}{ctx.Request.QueryString}";
            var requestInfo = $@"请求  第{totalCount}个请求 当前并发:{count}";
            await next(ctx);
            var counter2 = Interlocked.Decrement(ref RunningCounter);
            totalCount = Interlocked.Read(ref TotalCounter);
            st.Stop();
            var responseInfo = $@"响应  并发变化: {count}->{counter2} 当前总访问量:{totalCount}";

            ctx.Request.Headers.TryGetValue("Referer", out StringValues referer);
            ctx.Request.Headers.TryGetValue("User-Agent", out StringValues ua);

            logger.LogInformation("{content}", new
            {
                ApiPath = ctx.Request?.Path.Value,
                RequestPath = requestPath,
                Content = new
                {
                    ReqLength = ctx.Request.ContentLength,
                    ReqContentType = ctx.Request.ContentType,
                    ctx.Request.Host,
                    ctx.Request.Method,
                    Referer = referer.To<bool>(true, string.Empty),
                    UA = ua.To<bool>(true, string.Empty),
                    Client = "", // $"{ctx.Connection.RemoteIpAddress}:{ctx.Connection.RemotePort}-{Utils.ClientRealIP(ctx)}",
                    ResLength = ctx.Response.ContentLength,
                    ResContentType = ctx.Response.ContentType,
                    ResStatusCode = ctx.Response.StatusCode,
                },
                User = "",// jwtUser,
                Sys = ctx.Request?.Path.Value?.Split('/').Skip(1).FirstOrDefault(),
                PV = totalCount,
                st.ElapsedMilliseconds,
                Request = requestInfo,
                Response = responseInfo
            }); ;
        }
    }
}
